package com.activiti.flow.controller;

import com.activiti.basic.model.PageBean;
import com.activiti.basic.model.ResponseUtil;
import com.activiti.basic.model.WebResponse;
import com.activiti.flow.model.vo.ProcessDefinitionVO;
import com.activiti.flow.service.ProcessDefinitionService;
import com.fasterxml.jackson.databind.ObjectMapper;
import com.fasterxml.jackson.databind.node.ObjectNode;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import net.sf.json.JSONArray;
import net.sf.json.JSONObject;
import net.sf.json.JsonConfig;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RepositoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.history.HistoricTaskInstance;
import org.activiti.engine.repository.Model;
import org.activiti.engine.repository.ProcessDefinition;
import org.activiti.engine.runtime.ProcessInstance;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import javax.servlet.http.HttpServletResponse;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.*;

/**
 * 流程定义管理Controller
 *
 * @author beike
 * @date 2019年4月24日
 */
@Api(tags = "流程定义管理")
@RestController
@RequestMapping("/processDefinition")
public class ProcessDefinitionController {

    @Autowired
    private RepositoryService repositoryService;

    @Autowired
    private HistoryService historyService;

    @Autowired
    private ProcessDefinitionService processDefinitionService;

    @Autowired
    ObjectMapper objectMapper;

    /**
     * 流程定义查询
     *
     * @param page     当前页
     * @param rows     一页数据大小
     * @param name
     * @param response
     * @return
     * @throws Exception
     */
    @GetMapping("/list")
    public String list(@RequestParam(value = "page", required = false) String page, @RequestParam(value = "rows", required = false) String rows, String name, HttpServletResponse response) throws Exception {
        if (name == null) {
            name = "";
        }
        PageBean pageBean = new PageBean(Integer.parseInt(page), Integer.parseInt(rows));
        // 创建流程流程定义查询
        List<ProcessDefinition> processDefinition = repositoryService.createProcessDefinitionQuery()
                // 根据流程定义id降序排列
                .orderByProcessDefinitionId().desc()
                // 根据流程定义名称模糊查询
                .processDefinitionNameLike("%" + name + "%")
                // 返回带分页的结果集合
                .listPage(pageBean.getPageNo(), pageBean.getPageSize());
        // 获取总记录数
        long total = repositoryService.createProcessDefinitionQuery().processDefinitionNameLike("%" + name + "%").count();
        JsonConfig jsonConfig = new JsonConfig();
        jsonConfig.setExcludes(new String[]{"identityLinks", "processDefinition"});
        JSONObject result = new JSONObject();
        JSONArray jsonArray = JSONArray.fromObject(processDefinition, jsonConfig);
        result.put("rows", jsonArray);
        result.put("total", total);
        ResponseUtil.write(response, result);
        return null;
    }

    /**
     * 查看流程图
     *
     * @param deploymentId
     * @param diagramResourceName
     * @param response
     * @return
     * @throws Exception
     */
    @GetMapping("/showView")
    public String showView(String deploymentId, String diagramResourceName, HttpServletResponse response) throws Exception {
        InputStream inputStream = repositoryService.getResourceAsStream(deploymentId, diagramResourceName);
        OutputStream out = response.getOutputStream();
        for (int b = -1; (b = inputStream.read()) != -1; ) {
            out.write(b);
        }
        out.close();
        inputStream.close();
        return null;
    }

    /**
     * 查看流程图
     *
     * @param taskId
     * @param response
     * @return
     * @throws Exception
     */
    @GetMapping("/showViewByTaskId")
    public String showViewByTaskId(String taskId, HttpServletResponse response) throws Exception {
        HistoricTaskInstance hti = historyService.createHistoricTaskInstanceQuery().taskId(taskId).singleResult();
        // 获取流程定义id
        String processDefinitionId = hti.getProcessDefinitionId();
        ProcessDefinition pd = repositoryService.createProcessDefinitionQuery().processDefinitionId(processDefinitionId).singleResult();
        InputStream inputStream = repositoryService.getResourceAsStream(pd.getDeploymentId(), pd.getDiagramResourceName());
        OutputStream out = response.getOutputStream();
        for (int b = -1; (b = inputStream.read()) != -1; ) {
            out.write(b);
        }
        out.close();
        inputStream.close();
        return null;
    }

    /**
     * 复制流程定义
     *
     * @param id
     * @return
     * @throws Exception
     */
    @Transactional(readOnly = false)
    @PostMapping("/copy")
    public Model copy(@RequestParam("id") String id) throws Exception {
        Model sourceModel = repositoryService.getModel(id);
        ObjectNode sourceObjectNode = (ObjectNode) new ObjectMapper().readTree(repositoryService.getModelEditorSource(id));
        Model model = repositoryService.newModel();
        model.setKey(sourceModel.getKey() + UUID.randomUUID());
        //名称
        model.setName(sourceModel.getName() + "_copy");
        //分类
        model.setCategory(sourceModel.getCategory());
        //版本
        model.setVersion(0);
        //元数据 json 格式
        model.setMetaInfo(sourceModel.getMetaInfo());
        repositoryService.saveModel(model);
        ObjectNode editorNode = sourceObjectNode.deepCopy();
        ObjectNode properties = objectMapper.createObjectNode();
        properties.put("process_id", model.getKey());
        properties.put("process_author", "lms");
        properties.put("name", model.getName());
        editorNode.set("properties", properties);
        repositoryService.addModelEditorSource(model.getId(), editorNode.toString().getBytes("utf-8"));
        return model;
    }

}